PROJECT(libSDL2pp)

# meta
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

SET(SDL2PP_MAJOR_VERSION 0)
SET(SDL2PP_MINOR_VERSION 16)
SET(SDL2PP_PATCH_VERSION 0)

SET(SDL2PP_VERSION "${SDL2PP_MAJOR_VERSION}.${SDL2PP_MINOR_VERSION}.${SDL2PP_PATCH_VERSION}")

SET(SDL2PP_CXXSTD "c++11" CACHE STRING "Used c++ standard")

IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
	OPTION(SDL2PP_WITH_IMAGE "Enable SDL2_image support" ON)
	OPTION(SDL2PP_WITH_TTF "Enable SDL2_ttf support" ON)
	OPTION(SDL2PP_WITH_MIXER "Enable SDL2_mixer support" ON)
ELSE(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
	# please set SDL2PP_WITH_IMAGE, SDL2PP_WITH_TTF, SDL2PP_WITH_MIXER in parent project as needed
ENDIF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)

# depends
FIND_PACKAGE(SDL2 REQUIRED)
SET(SDL2_ALL_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
SET(SDL2_ALL_LIBRARIES ${SDL2_LIBRARY})
SET(SDL2_ALL_PKGCONFIG_MODULES sdl2)
SET(SDL2PP_EXTRA_LIBRARIES ${SDL2MAIN_LIBRARY})
SET(SDL2PP_EXTRA_PKGCONFIG_LIBRARIES ${SDL2MAIN_LIBRARY})

IF(MINGW)
	SET(MINGW32_LIBRARY "mingw32" CACHE STRING "mingw32 library")
	SET(SDL2PP_EXTRA_LIBRARIES ${MINGW32_LIBRARY} ${SDL2PP_EXTRA_LIBRARIES})
	SET(SDL2PP_EXTRA_PKGCONFIG_LIBRARIES "-l${MINGW32_LIBRARY} ${SDL2PP_EXTRA_PKGCONFIG_LIBRARIES}")
ENDIF(MINGW)

IF(SDL2PP_WITH_IMAGE)
	FIND_PACKAGE(SDL2_image REQUIRED)
	SET(SDL2_ALL_INCLUDE_DIRS ${SDL2_ALL_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIR})
	SET(SDL2_ALL_LIBRARIES ${SDL2_ALL_LIBRARIES} ${SDL2_IMAGE_LIBRARY})
	SET(SDL2_ALL_PKGCONFIG_MODULES "${SDL2_ALL_PKGCONFIG_MODULES} SDL2_image")
ELSE(SDL2PP_WITH_IMAGE)
	MESSAGE(STATUS "SDL2_image support disabled")
ENDIF(SDL2PP_WITH_IMAGE)

IF(SDL2PP_WITH_TTF)
	FIND_PACKAGE(SDL2_ttf REQUIRED)
	SET(SDL2_ALL_INCLUDE_DIRS ${SDL2_ALL_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIR})
	SET(SDL2_ALL_LIBRARIES ${SDL2_ALL_LIBRARIES} ${SDL2_TTF_LIBRARY})
	SET(SDL2_ALL_PKGCONFIG_MODULES "${SDL2_ALL_PKGCONFIG_MODULES} SDL2_ttf")
ELSE(SDL2PP_WITH_TTF)
	MESSAGE(STATUS "SDL2_ttf support disabled")
ENDIF(SDL2PP_WITH_TTF)

IF(SDL2PP_WITH_MIXER)
	FIND_PACKAGE(SDL2_mixer REQUIRED)
	SET(SDL2_ALL_INCLUDE_DIRS ${SDL2_ALL_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIR})
	SET(SDL2_ALL_LIBRARIES ${SDL2_ALL_LIBRARIES} ${SDL2_MIXER_LIBRARY})
	SET(SDL2_ALL_PKGCONFIG_MODULES "${SDL2_ALL_PKGCONFIG_MODULES} SDL2_mixer")
ELSE(SDL2PP_WITH_MIXER)
	MESSAGE(STATUS "SDL2_mixer support disabled")
ENDIF(SDL2PP_WITH_MIXER)

# compiler flags & definitions
IF(MSVC)
	SET(SDL2PP_WARNINGS "${SDL2PP_WARNINGS} /W3")
ELSE(MSVC)
	SET(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage")
	SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --coverage")
	SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} --coverage")

	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=${SDL2PP_CXXSTD}")
	SET(SDL2PP_WARNINGS "${SDL2PP_WARNINGS} -Wall -Wextra -pedantic")

	INCLUDE(AppendCXXFlagIfSupported)

	# enable for more cleanups
	#APPEND_CXX_FLAG_IF_SUPPORTED(-Weverything SDL2PP_WARNINGS)

	# always enables some -Weverything warnings
	APPEND_CXX_FLAG_IF_SUPPORTED(-Wmissing-prototypes SDL2PP_WARNINGS)
	APPEND_CXX_FLAG_IF_SUPPORTED(-Wtautological-compare SDL2PP_WARNINGS)
	APPEND_CXX_FLAG_IF_SUPPORTED(-Wshorten-64-to-32 SDL2PP_WARNINGS)

	# disable some -Weverything warnings
	#APPEND_CXX_FLAG_IF_SUPPORTED(-Wno-c++98-compat SDL2PP_WARNINGS)
	#APPEND_CXX_FLAG_IF_SUPPORTED(-Wno-padded SDL2PP_WARNINGS)
ENDIF(MSVC)

LIST(REMOVE_DUPLICATES SDL2_ALL_INCLUDE_DIRS)

INCLUDE_DIRECTORIES(BEFORE ${PROJECT_SOURCE_DIR})
INCLUDE_DIRECTORIES(SYSTEM ${SDL2_ALL_INCLUDE_DIRS})

INCLUDE(CheckCompile)
CHECK_COMPILE(
	SDL2PP_WITH_EXPERIMENTAL_OPTIONAL
	"#include <experimental/optional>\nint main() { std::experimental::optional<int> o; return !o; }"
	"experimental/optional header"
)

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SDL2PP_WARNINGS}")

# config.h
CONFIGURE_FILE(
	SDL2pp/Config.hh.in
	SDL2pp/Config.hh
)

INCLUDE_DIRECTORIES(BEFORE ${PROJECT_BINARY_DIR})

# sources
SET(LIBRARY_SOURCES
	SDL2pp/AudioDevice.cc
	SDL2pp/AudioLock.cc
	SDL2pp/AudioSpec.cc
	SDL2pp/Color.cc
	SDL2pp/Exception.cc
	SDL2pp/Point.cc
	SDL2pp/RWops.cc
	SDL2pp/Rect.cc
	SDL2pp/Renderer.cc
	SDL2pp/SDL.cc
	SDL2pp/Surface.cc
	SDL2pp/SurfaceLock.cc
	SDL2pp/Texture.cc
	SDL2pp/TextureLock.cc
	SDL2pp/Wav.cc
	SDL2pp/Window.cc
)

SET(LIBRARY_HEADERS
	SDL2pp/AudioDevice.hh
	SDL2pp/AudioSpec.hh
	SDL2pp/Color.hh
	SDL2pp/ContainerRWops.hh
	SDL2pp/Exception.hh
	SDL2pp/Optional.hh
	SDL2pp/Point.hh
	SDL2pp/RWops.hh
	SDL2pp/Rect.hh
	SDL2pp/Renderer.hh
	SDL2pp/SDL.hh
	SDL2pp/SDL2pp.hh
	SDL2pp/StreamRWops.hh
	SDL2pp/Surface.hh
	SDL2pp/Texture.hh
	SDL2pp/Wav.hh
	SDL2pp/Window.hh
)

SET(LIBRARY_EXTERNAL_HEADERS
	SDL2pp/external/libcpp_optional.hh
)

# optional sources
IF(SDL2PP_WITH_TTF)
	SET(LIBRARY_SOURCES
		${LIBRARY_SOURCES}
		SDL2pp/SDLTTF.cc
		SDL2pp/Font.cc
	)
	SET(LIBRARY_HEADERS
		${LIBRARY_HEADERS}
		SDL2pp/SDLTTF.hh
		SDL2pp/Font.hh
	)
ENDIF(SDL2PP_WITH_TTF)

IF(SDL2PP_WITH_IMAGE)
	SET(LIBRARY_SOURCES
		${LIBRARY_SOURCES}
		SDL2pp/SDLImage.cc
	)
	SET(LIBRARY_HEADERS
		${LIBRARY_HEADERS}
		SDL2pp/SDLImage.hh
	)
ENDIF(SDL2PP_WITH_IMAGE)

IF(SDL2PP_WITH_MIXER)
	SET(LIBRARY_SOURCES
		${LIBRARY_SOURCES}
		SDL2pp/Chunk.cc
		SDL2pp/Mixer.cc
		SDL2pp/Music.cc
		SDL2pp/SDLMixer.cc
	)
	SET(LIBRARY_HEADERS
		${LIBRARY_HEADERS}
		SDL2pp/Chunk.hh
		SDL2pp/Mixer.hh
		SDL2pp/Music.hh
		SDL2pp/SDLMixer.hh
	)
ENDIF(SDL2PP_WITH_MIXER)

# targets
INCLUDE(GenerateExportHeader)

IF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
	# options
	OPTION(SDL2PP_WITH_EXAMPLES "Build examples" ON)
	OPTION(SDL2PP_WITH_TESTS "Build tests" ON)
	OPTION(SDL2PP_ENABLE_LIVE_TESTS "Enable live tests (require X11 display and audio device)" ON)
	OPTION(SDL2PP_STATIC "Build static library instead of shared one" OFF)

	# library
	IF(SDL2PP_STATIC)
		ADD_LIBRARY(SDL2pp STATIC ${LIBRARY_SOURCES} ${LIBRARY_HEADERS})
	ELSE(SDL2PP_STATIC)
		ADD_LIBRARY(SDL2pp SHARED ${LIBRARY_SOURCES} ${LIBRARY_HEADERS})
		TARGET_LINK_LIBRARIES(SDL2pp ${SDL2_ALL_LIBRARIES})
		SET_TARGET_PROPERTIES(SDL2pp PROPERTIES VERSION 8.3.0 SOVERSION 8)
	ENDIF(SDL2PP_STATIC)

	GENERATE_EXPORT_HEADER(SDL2pp EXPORT_FILE_NAME SDL2pp/Export.hh)

	SET(SDL2PP_LIBRARIES ${SDL2PP_EXTRA_LIBRARIES} SDL2pp ${SDL2_ALL_LIBRARIES})

	# examples and tests
	IF(SDL2PP_WITH_EXAMPLES)
		ADD_SUBDIRECTORY(examples)
	ENDIF(SDL2PP_WITH_EXAMPLES)

	IF(SDL2PP_WITH_TESTS)
		ENABLE_TESTING()
		ADD_SUBDIRECTORY(tests)
	ENDIF(SDL2PP_WITH_TESTS)

	# doxygen
	FIND_PACKAGE(Doxygen)
	IF(DOXYGEN_FOUND)
		CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
		ADD_CUSTOM_TARGET(doxygen
			${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
			WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
			COMMENT "Generating API documentation with Doxygen" VERBATIM
		)
	ENDIF(DOXYGEN_FOUND)

	# pkgconfig and cmake modules
	SET(CMAKEMODDIR share/cmake/Modules CACHE STRING "directory where to install cmake module")
	SET(PKGCONFIGDIR lib/pkgconfig CACHE STRING "directory where to install pkg-config files")
	IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly")
		SET(PKGCONFIGDIR libdata/pkgconfig)
	ENDIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "DragonFly")

	INCLUDE(Join)

	JOIN_QUOTED("${SDL2PP_EXTRA_LIBRARIES}" SDL2PP_EXTRA_LIBRARIES_STR)
	JOIN_QUOTED("${SDL2_ALL_LIBRARIES}" SDL2_ALL_LIBRARIES_STR)
	JOIN_QUOTED("${SDL2_ALL_INCLUDE_DIRS}" SDL2_ALL_INCLUDE_DIRS_STR)

	CONFIGURE_FILE(
		sdl2pp.pc.in
		sdl2pp.pc
		@ONLY
	)

	CONFIGURE_FILE(
		FindSDL2PP.cmake.in
		FindSDL2PP.cmake
		@ONLY
	)

	# install
	INSTALL(FILES
		${LIBRARY_HEADERS}
		${PROJECT_BINARY_DIR}/SDL2pp/Config.hh
		${PROJECT_BINARY_DIR}/SDL2pp/Export.hh
		DESTINATION include/SDL2pp
	)
	INSTALL(FILES ${LIBRARY_EXTERNAL_HEADERS} DESTINATION include/SDL2pp/external)
	INSTALL(TARGETS SDL2pp
		RUNTIME DESTINATION bin
		LIBRARY DESTINATION lib
		ARCHIVE DESTINATION lib
	)
	INSTALL(FILES ${PROJECT_BINARY_DIR}/sdl2pp.pc DESTINATION ${PKGCONFIGDIR})
	INSTALL(FILES ${PROJECT_BINARY_DIR}/FindSDL2PP.cmake DESTINATION ${CMAKEMODDIR})

	MESSAGE(STATUS "libSDL2pp ${SDL2PP_VERSION} standalone build")
ELSE(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
	# library
	ADD_LIBRARY(SDL2pp STATIC ${LIBRARY_SOURCES} ${LIBRARY_HEADERS})
	GENERATE_EXPORT_HEADER(SDL2pp EXPORT_FILE_NAME SDL2pp/Export.hh)

	# provide variables to parent
	SET(SDL2PP_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${SDL2_ALL_INCLUDE_DIRS} PARENT_SCOPE)
	SET(SDL2PP_LIBRARIES ${SDL2PP_EXTRA_LIBRARIES} SDL2pp ${SDL2_ALL_LIBRARIES} PARENT_SCOPE)

	MESSAGE(STATUS "libSDL2pp ${SDL2PP_VERSION} bundled build")
ENDIF(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
